# -*- coding: UTF-8 -*-

import os.path
import codecs
import random
import json
import copy
from kivy import Logger
from model.dictionaryinfo import DictionaryInfo


class DictionaryWord():
    def __init__(self, text, complexity):
        self.text = text
        self.complexity = complexity


class Dictionary():
    def __init__(self, dicts_to_load):
        """ Loading dictionaries, witch you give it in "dicts_to_load"

        Args:
            dicts_to_load: (list of string)
        Return:
            None
        """
        Logger.warning(str(dicts_to_load))
        dictionary_words_dict = {}
        self.dictionary_words = []
        for name in dicts_to_load:
            path_to_dictionary = os.path.join(os.path.dirname(__file__),
                                              '..', 'data', name)
            dictionary_file = codecs.open(path_to_dictionary, encoding='utf-8',
                                          mode='r')
            for line in dictionary_file:
                (word, complexity) = line.split()
                if not (word in dictionary_words_dict):
                    dictionary_words_dict[word] = int(complexity)
                else:
                    dictionary_words_dict[word] =\
                        min(dictionary_words_dict[word], int(complexity))

            dictionary_file.close()

        for word in dictionary_words_dict:
            self.dictionary_words.append(
                DictionaryWord(word, dictionary_words_dict[word]))

        random.shuffle(self.dictionary_words)
        self.next_word = 0

        Logger.debug('Loaded %d words' %
                    (len(self.dictionary_words)))

    def get_words(self, count, list_of_deny_strings):
        """ Gives list of count strings -- random words from dictionary

        Args:
            count: (int)
            list_of_deny_strings: list of strings

        Return:
            list of strings
        """
        set_of_deny_strings = set(list_of_deny_strings)
        chosen_words = []
        cnt_iteration = 0
        while len(chosen_words) < count:
            cnt_iteration += 1
            if cnt_iteration > 2:
                break
            for i in xrange(self.next_word, len(self.dictionary_words)):
                word = self.dictionary_words[i]
                if word.text in set_of_deny_strings:
                    continue
                chosen_words.append(word.text)
                set_of_deny_strings.add(word.text)
                if len(chosen_words) >= count:
                    self.next_word = i + 1
                    break
            else:
                random.shuffle(self.dictionary_words)
                self.next_word = 0
        return chosen_words

    loaded_dictionary = None

    @staticmethod
    def get_dict(app_settings):
        dicts_to_load = []
        if Dictionary.loaded_dictionary is None:
            for cur_dict in DictionaryInfo.parse_dictionaries_metadata():
                if cur_dict.file_name in DictionaryInfo.enabled_dictionaries:
                    cur_dict.enable_by_default = \
                        DictionaryInfo.enabled_dictionaries[cur_dict.file_name]
                if cur_dict.enable_by_default:
                    dicts_to_load.append(cur_dict.file_name)
            Dictionary.loaded_dictionary = Dictionary(dicts_to_load)

        return Dictionary.loaded_dictionary

    @staticmethod
    def invalidate():
        Dictionary.loaded_dictionary = None

    @staticmethod
    def make_json():
        list_dict = DictionaryInfo.parse_dictionaries_metadata()
        all_json = [{u"type": u"title", u"title": u"Dictionaries Defaults"}]
        cur_dict_json = {
            u"type": u"bool",
            u"title": u"",
            u"desc": u"",
            u"section": u"Dictionaries Defaults",
            u"key": u""
        }

        for cur_dict in list_dict:
            cur_dict_json[u"title"] = cur_dict.file_name
            cur_dict_json[u"key"] = cur_dict.file_name
            cur_dict_json[u"desc"] = cur_dict.description
            all_json.append(cur_dict_json.copy())

        return json.dumps(all_json, encoding='utf-8', sort_keys=True)
